package spring.cloud.tasks.common;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.KeeperException;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Setter
@Getter
public class CuratorUtils {
    private CuratorUtils() {
    }

    /**
     * Not use curator's deletingChildrenIfNeeded, to avoid this bug https://github.com/apache/curator/pull/235
     */
    public static void deleteRecursive(final CuratorFramework curatorFramework, final String path) throws Exception {
        List<String> children = new ArrayList<>();
        try {
            children = curatorFramework.getChildren().forPath(path);
        } catch (KeeperException.NoNodeException e) {
            log.debug("no node exception throws during get children of path:" + path, e);
            return;
        }
        if (children != null && children.size() > 0) {
            for (String child : children) {
                deleteRecursive(curatorFramework, path + "/" + child);
            }
        }
        try {
            curatorFramework.delete().guaranteed().forPath(path);//must guaranteed
        } catch (KeeperException.NoNodeException e) {
            // when multi-client delete the children concurrently, then will throw such exception. and you need do nothing.
            log.warn("try to delete path:" + path + " ,but the node is not existed", e);
        } catch (KeeperException.NotEmptyException e) {
            //when multi-client update the children concurrently,the children is not empty
            log.warn("try to delete path:" + path + " ,but the node is not empty", e);
            deleteRecursive(curatorFramework, path);//为了避免出现这种情况 调度框架在设计的时候 只允许一个线程操作某个节点。
        }
    }

}
